package tools.phylip;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;

public class PhylipUtils {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		if(args.length>0){
			if(args[0].equals("phy2fa")&&args.length==2){
				phy2fa(args[1]);
			}else if(args[0].equals("multiPhy2fa")&&args.length==3){
				multiPhy2fa(args[1],args[2]);
			}else if(args[0].equals("giTable2phyTree")&&args.length==2){
				giTable2phyTree(args[1],2,"\t");
			}else if(args[0].equals("giTable2phyTree")&&args.length==3){
				giTable2phyTree(args[1],Integer.parseInt(args[2]),"\t");
			}else if(args[0].equals("isodataClust2phyTree")&&args.length==3){
				isodataClust2phyTree(args[1],args[2]);
			}else if(args[0].equals("giTable2phyTree")&&args.length==4){
				giTable2phyTree(args[1],Integer.parseInt(args[2]),args[3]);
			}else{
				System.err.println(printHelp());
				System.exit(616);
			}
		}else{
			System.err.println(printHelp());
			System.exit(616);
		}
		System.exit(0);
	}

	private static String printHelp(){
		String help="PhylipUtils contains different methods for manipulation in association to Phylip\n";
		help+="Usage: PhylipUtils <cmd> <input>\n";
		help+="where <cmd> is:\n";
		help+="phy2fa - reads a phy-file and prints the sequences in fa-format.\n";
		help+="\t<input> = <phy-file>\n";
		help+="multiPhy2fa - reads a multiple phy-file and prints the sequences in fa-format, with the given prefix and a increasing index\n";
		help+="\t<input> = <phy-file> <fa-prefix>\n";
		help+="giTable2phyTree - converts a file on the form (gi\\tcluster) to a phylip tree\n";
		help+="\t<input> = <giTable file> <cluster column=1 (starts with 0)> <sep=\\t>\n";
		help+="isodataClust2phyTree - converts an isodata cluster file to a phylip tree\n";
		help+="\t<input> = <isodata cluster file> <name file> \n";
		
		return help;
	}
	
	private static void isodataClust2phyTree(String isoclustFile,String nameFile)throws Exception{
		BufferedReader in= new BufferedReader(new FileReader(nameFile));
		HashMap<String, String> code= new HashMap<String, String>();
		String[] l;
		for(String s=in.readLine();s!=null;s=in.readLine()){
			l=s.split("\t");
			if(l.length>1){
				code.put(l[0], l[1]);
			}
		}
		in= new BufferedReader(new FileReader(isoclustFile));
		HashMap<String, ArrayList<String>> clusters= new HashMap<String, ArrayList<String>>();
		for(String s=in.readLine();s!=null;s=in.readLine()){
			l=s.split(",");
			if(l.length>2){
				if(!clusters.containsKey(l[2])){
					clusters.put(l[2], new ArrayList<String>());
				}
				clusters.get(l[2]).add(code.get(l[0]));
			}
		}
		printphyTree(clusters);
	}
	
	private static void giTable2phyTree(String giTableFile, int clusterColumn,String separator)throws Exception{
		BufferedReader in= new BufferedReader(new FileReader(giTableFile));
		HashMap<String, ArrayList<String>> clusters= new HashMap<String, ArrayList<String>>();
		//read structure
		for(String s=in.readLine();s!=null;s=in.readLine()){
			String[] l=s.split(separator);
			if(l.length>clusterColumn){
				if(!clusters.containsKey(l[clusterColumn])){
					clusters.put(l[clusterColumn], new ArrayList<String>());
				}
				clusters.get(l[clusterColumn]).add(l[0]);
			}
		}
		//print tree
		printphyTree(clusters);
	}
	
	private static void printphyTree(HashMap<String, ArrayList<String>>clusters){
		boolean firstL0=true;
		System.out.print("(");
		for (ArrayList<String> cluster : clusters.values()) {
			if(firstL0){
				firstL0=false;
			}else{
				System.out.print(",");
			}
			System.out.print("('"+cluster.get(0)+"'");
			for(int i=1;i<cluster.size();i++){
				System.out.print(",'"+cluster.get(i)+"'");
			}
			System.out.print(")");
		}
		System.out.println(");");
	}
	
	private static void multiPhy2fa(String phyFile,String prefix)throws Exception{
		Phylipparser pp=new Phylipparser(phyFile);
		BufferedWriter out;
		for(int i=1;pp.hasMore();i++){
			if(i%10==0){
				System.out.println(i);
			}
			out=new BufferedWriter(new FileWriter(prefix+"_"+i+".fa"));
			for (PhylipSeq ps : pp.nextSubsection()) {
				out.write(ps.toFastaSeq()+"\n");
			}
			out.close();
		}
	}
	
	private static void phy2fa(String phyFile)throws Exception{
		Phylipparser pp=new Phylipparser(phyFile);
		if(pp.hasMore()){
			for (PhylipSeq ps : pp.nextSubsection()) {
				System.out.println(ps.toFastaSeq());
			}
			if(pp.hasMore()){
				System.err.println("This is a multiple phylip-file, but only the first subsection was read...");
			}
		}
	}
}
